package org.funsciencewithyourcomputer.client;

import java.util.Date;

import com.google.gwt.user.client.Cookies;

/**
 * Cookie is used to save high scores. Format: version1: High
 * Score,name1,score1,name2,score2,..: Other Category,name1,score1,..
 */
public class HighScore {

	static final String COOKIE_HIGH_SCORE = "HIGH_SCORE";

	static final int MAX_HIGH_SCORE = 10;

	public String[] originalName = new String[MAX_HIGH_SCORE];

	public int[] originalScore = new int[MAX_HIGH_SCORE];

	public String[] actionName = new String[MAX_HIGH_SCORE];

	public int[] actionScore = new int[MAX_HIGH_SCORE];
	
	public static final String NO_ENTRY = "--";
	
	static final String SIGNATURE = "STEG01";

	public static HighScore readCookie() {
		HighScore result = new HighScore();
		for (int i = 0; i < MAX_HIGH_SCORE; i++) {
			result.originalName[i] = NO_ENTRY;
			result.actionName[i] = NO_ENTRY;
		}
		String cookie = Cookies.getCookie(COOKIE_HIGH_SCORE);
		if (cookie == null || !cookie.startsWith(SIGNATURE))
			return result;
		String[] tokens = cookie.substring(SIGNATURE.length()).split(",");
		for (int i = 0; i < tokens.length; i += 2) {
			if (i < MAX_HIGH_SCORE * 2) {
				result.originalName[i / 2] = tokens[i];
				result.originalScore[i / 2] = Integer.parseInt(tokens[i + 1]);
			} else {
				result.actionName[i / 2 - MAX_HIGH_SCORE] = tokens[i];
				result.actionScore[i / 2 - MAX_HIGH_SCORE] = Integer.parseInt(tokens[i + 1]);
			}
		}
		return result;
	}

	/**
	 * Update given
	 * 
	 * @param ranking
	 * @param newScore
	 * @return
	 */
	public static boolean saveCookie(int newScore, int mode) {
		HighScore ranking = readCookie();
		int rank = -1;
		if (mode == Lifecycle.MODE_ORIGINAL) {
			for (int i = 0; i < MAX_HIGH_SCORE; i++) {
				if (ranking.originalName[i].equals(NO_ENTRY)) {
					rank = i;
					break;
				}
				if (ranking.originalScore[i] > newScore) {
					rank = i;
					break;
				}
			}
			if (rank != -1)
				// TODO ask for user name
				insert("PLAYER1", newScore, ranking, rank, mode);
		} else {
			for (int i = 0; i < MAX_HIGH_SCORE; i++) {
				if (ranking.actionName[i].equals(NO_ENTRY)) {
					rank = i;
					break;
				}
				if (ranking.actionScore[i] < newScore) {
					rank = i;
					break;
				}
			}
			if (rank != -1)
				// TODO ask for user name
				insert("PLAYER1", newScore, ranking, rank, mode);
		}
		if (rank != -1) {
			String result = "";
			for (int i = 0; i < MAX_HIGH_SCORE; i++)
				result += getName(ranking.originalName[i]) + ","
						+ ranking.originalScore[i] + ",";
			for (int i = 0; i < MAX_HIGH_SCORE; i++)
				result += getName(ranking.actionName[i]) + "," + ranking.actionScore[i]
						+ ",";
			result = result.substring(0, result.length() - 1);
			Date oneYear = new Date(System.currentTimeMillis() + 365 * 24 * 60
					* 60 * 1000);
			Cookies.setCookie(COOKIE_HIGH_SCORE, SIGNATURE+result, oneYear);
			return true;
		}
		return false;
	}

	static String getName(String name) {
		return name != null ? name : NO_ENTRY;
	}
	static void insert(String newName, int newScore, HighScore ranking,
			int rank, int mode) {
		String[] name = mode == Lifecycle.MODE_ORIGINAL ? ranking.originalName
				: ranking.actionName;
		int[] score = mode == Lifecycle.MODE_ORIGINAL ? ranking.originalScore
				: ranking.actionScore;
		if (name[rank] != null) {
			for (int i = name.length - 2; i >= rank; i--) {
				name[i + 1] = name[i];
				score[i + 1] = score[i];
			}
		}
		name[rank] = newName;
		score[rank] = newScore;
	}
}
